#include "pch.h"
#include "SinglePreview.h"

#include "PreviewContentProvider.h"

using namespace NiklasKarl::WarpCam::Native;
using namespace Windows::Phone::Input::Interop;
using namespace Windows::UI;
using namespace Windows::Foundation;
using namespace Windows::Phone::Graphics::Interop;

SinglePreview::SinglePreview() :
	m_resolution(0.0F, 0.0F),
	m_propertyChanged(TRUE)
{
	m_background[0] = 0.0F;
	m_background[1] = 0.0F;
	m_background[2] = 0.0F;
	m_background[3] = 1.0F;
}

IDrawingSurfaceBackgroundContentProvider^ SinglePreview::CreateContentProvider()
{
	PreviewContentProvider *provider = Microsoft::WRL::Make<PreviewContentProvider>(this).Get();
	return reinterpret_cast<IDrawingSurfaceBackgroundContentProvider^>(provider);
}

void SinglePreview::SetManipulationHost(DrawingSurfaceManipulationHost^ manipulationHost)
{
	/* register for input events */
}

Windows::Foundation::Size SinglePreview::Resolution::get()
{
	return m_resolution;
}

void SinglePreview::Resolution::set(Windows::Foundation::Size size)
{
	if (m_resolution != size)
	{
		m_resolution = size;
		m_propertyChanged = TRUE;
	}
}

Nokia::Graphics::Imaging::IImageProvider^ SinglePreview::PreviewSource::get()
{
	return m_source;
}

void SinglePreview::PreviewSource::set(Nokia::Graphics::Imaging::IImageProvider^ source)
{
	m_source = source;
}

Nokia::Graphics::Imaging::Rotation SinglePreview::PreviewRotation::get()
{
	return m_rotation;
}

void SinglePreview::PreviewRotation::set(Nokia::Graphics::Imaging::Rotation rotation)
{
	if (m_rotation != rotation)
	{
		m_rotation = rotation;
		m_propertyChanged = TRUE;
	}
}

Nokia::Graphics::Imaging::FlipMode SinglePreview::PreviewFlip::get()
{
	return m_flip;
}

void SinglePreview::PreviewFlip::set(Nokia::Graphics::Imaging::FlipMode mode)
{
	if (m_flip != mode)
	{
		m_flip = mode;
		m_propertyChanged = TRUE;
	}
}

Rect SinglePreview::PreviewRect::get()
{
	return m_rect;
}

void SinglePreview::PreviewRect::set(Rect rect)
{
	if (m_rect != rect)
	{
		m_rect = rect;
		m_propertyChanged = TRUE;
	}
}

Color SinglePreview::Background::get()
{
	Color color = Color();
	color.R = (BYTE) (m_background[0] * 255.0F);
	color.G = (BYTE) (m_background[1] * 255.0F);
	color.B = (BYTE) (m_background[2] * 255.0F);
	color.A = (BYTE) (m_background[3] * 255.0F);

	return color;
}

void SinglePreview::Background::set(Color color)
{
	m_background[0] = ((FLOAT) color.R) / 255.0F;
	m_background[1] = ((FLOAT) color.G) / 255.0F;
	m_background[2] = ((FLOAT) color.B) / 255.0F;
	m_background[3] = ((FLOAT) color.A) / 255.0F;
}

HRESULT SinglePreview::Connect(IDrawingSurfaceRuntimeHostNative* host, ID3D11Device1* pDevice)
{
	m_renderer = ref new SinglePreviewRenderer();
	m_renderer->CreateDeviceResources(pDevice);

	return S_OK;
}

void SinglePreview::Disconnect()
{
	m_renderer->ReleaseDeviceResources();
}

HRESULT SinglePreview::PrepareResources(const LARGE_INTEGER* presentTargetTime, DrawingSurfaceSizeF* desiredRenderTargetSize)
{
	desiredRenderTargetSize->width = m_resolution.Width;
	desiredRenderTargetSize->height = m_resolution.Height;

	return S_OK;
}

HRESULT SinglePreview::Draw(ID3D11Device1* pDevice, ID3D11DeviceContext1* pContext, ID3D11RenderTargetView* pRenderTargetView)
{
	if (m_renderer->CheckForDeviceChange(pDevice))
	{
		m_propertyChanged = TRUE;
	}

	if (m_propertyChanged)
	{
		m_renderer->UpdateForPropertyChange(
			m_resolution,
			m_rect,
			m_rotation,
			m_flip,
			pContext
			);

		m_propertyChanged = FALSE;
	}

	m_renderer->Update(m_source, pContext);

	pContext->ClearRenderTargetView(pRenderTargetView, m_background);
	pContext->OMSetRenderTargets(1, &pRenderTargetView, nullptr);

	m_renderer->Render(pDevice, pContext);

	return S_OK;
}